package com.znyj.cloud.chain.httphandler;

import com.alibaba.fastjson.JSONObject;
import com.znyj.cloud.chain.dispatch.SimpleUrlHandlerMapping;
import com.znyj.cloud.chain.util.HttpUtil;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelFutureListener;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.handler.codec.http.FullHttpResponse;
import io.netty.handler.codec.http.HttpRequest;
import org.apache.log4j.Logger;

import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;


/**
 * Created by gaoliwei on 15-2-10.
 */
@ChannelHandler.Sharable
@Component
public class HttpDispatcherHandler extends SimpleChannelInboundHandler<HttpRequest> {

    private static final Logger LOG = Logger.getLogger(HttpDispatcherHandler.class);

    @Resource
    private SimpleUrlHandlerMapping simpleUrlHandlerMapping;

    @Override
    protected void channelRead0(ChannelHandlerContext ctx, HttpRequest msg) throws Exception {

        dispatch(ctx, msg);

    }

    private List<ByteBuf> dispatch(ChannelHandlerContext ctx, HttpRequest msg) {
        Object back = simpleUrlHandlerMapping.execute(ctx, msg);
        if (null != back) {
            return (List<ByteBuf>) back;
        }
        return new ArrayList<>();
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        if (cause instanceof IOException) {
            LOG.info("IOException..");
            return;
        }
        LOG.error("handle error", cause);
        JSONObject responseJson = new JSONObject();
        responseJson.put("error", "handler error");
        FullHttpResponse response = HttpUtil.getDefaultJsonFailResponse(responseJson);
        LOG.error("handler response" + response);
        ctx.writeAndFlush(response).addListener(ChannelFutureListener.CLOSE);
    }

}
